package crmdna.api.endpoint;

import java.util.Date;

import javax.annotation.Nullable;
import javax.inject.Named;
import javax.servlet.http.HttpServletRequest;

import com.google.api.server.spi.config.Api;
import com.google.api.server.spi.config.ApiMethod;
import com.google.api.server.spi.config.ApiMethod.HttpMethod;
import com.google.appengine.api.users.User;

import crmdna.common.APIResponse;
import crmdna.common.APIResponse.Status;
import crmdna.common.DateUtils;
import crmdna.common.DateUtils.DateRange;
import crmdna.common.RequestInfo;
import crmdna.common.StopWatch;
import crmdna.common.Utils;
import crmdna.interaction.Interaction;
import crmdna.interaction.Interaction.InteractionType;
import crmdna.interaction.InteractionProp;
import crmdna.interaction.InteractionQueryCondtion;
import crmdna.interaction.InteractionQueryResult;

@Api(name = "interaction")
public class InteractionApi {
	@ApiMethod(path = "createInteraction", httpMethod = HttpMethod.POST)
	public APIResponse createInteraction(
			@Nullable @Named("client") String client,
			@Named("memberId") long memberId,
			@Named("interactionType") InteractionType interactionType,
			@Named("content") String content,
			@Nullable @Named("showStackTrace") Boolean showStackTrace,
			HttpServletRequest req, User user) {

		if (null == client)
			client = "isha";

		String login = null;

		try {
			StopWatch sw = StopWatch.createStarted();

			login = Utils.getLoginEmail(user);

			InteractionProp prop = Interaction.createInteraction(client,
					memberId, content, interactionType, new Date(), login);

			return new APIResponse().status(Status.SUCCESS).object(prop)
					.processingTimeInMS(sw.msElapsed());

		} catch (Exception ex) {
			return Utils.toAPIResponse(ex, showStackTrace, new RequestInfo()
					.client(client).req(req).login(login));
		}
	}

	@ApiMethod(path = "updateInteraction", httpMethod = HttpMethod.POST)
	public APIResponse updateInteraction(
			@Nullable @Named("client") String client,
			@Named("interactionId") long interactionId,
			@Nullable @Named("newMemberId") Long newMemberId,
			@Nullable @Named("newInteractionType") InteractionType newInteractionType,
			@Nullable @Named("newUserEmail") String newUserEmail,
			@Nullable @Named("showStackTrace") Boolean showStackTrace,
			HttpServletRequest req, User user) {

		if (null == client)
			client = "isha";

		String login = null;

		try {
			StopWatch sw = StopWatch.createStarted();

			login = Utils.getLoginEmail(user);

			InteractionProp prop = Interaction.updateInteraction(client,
					interactionId, newMemberId, newInteractionType,
					newUserEmail, login);

			return new APIResponse().status(Status.SUCCESS).object(prop)
					.processingTimeInMS(sw.msElapsed());

		} catch (Exception ex) {
			return Utils.toAPIResponse(ex, showStackTrace, new RequestInfo()
					.client(client).req(req).login(login));
		}
	}

	@ApiMethod(path = "deleteInteraction", httpMethod = HttpMethod.DELETE)
	public APIResponse deleteInteraction(
			@Nullable @Named("client") String client,
			@Named("interactionId") long interactionId,
			@Nullable @Named("showStackTrace") Boolean showStackTrace,
			HttpServletRequest req, User user) {

		if (null == client)
			client = "isha";

		String login = null;

		try {
			StopWatch sw = StopWatch.createStarted();
			login = Utils.getLoginEmail(user);

			Interaction.deleteInteraction(client, interactionId, login);

			return new APIResponse().status(Status.SUCCESS)
					.object("interaction Id [" + interactionId + "] deleted")
					.processingTimeInMS(sw.msElapsed());

		} catch (Exception ex) {
			return Utils.toAPIResponse(ex, showStackTrace, new RequestInfo()
					.client(client).req(req).login(login));
		}
	}

	@ApiMethod(path = "query", httpMethod = HttpMethod.GET)
	public APIResponse query(
			@Nullable @Named("client") String client,
			@Nullable @Named("memberId") Long memberId,
			@Nullable @Named("userId") Long userId,
			@Nullable @Named("interactionType") InteractionType interactionType,
			@Nullable @Named("dateRange") DateRange dateRange,
			@Nullable @Named("startIndex") Integer startIndex,
			@Nullable @Named("numResults") Integer numResults,
			@Nullable @Named("showStackTrace") Boolean showStackTrace,
			HttpServletRequest req, User user) {

		if (null == client)
			client = "isha";

		String login = null;

		try {
			StopWatch sw = StopWatch.createStarted();
			login = Utils.getLoginEmail(user);

			InteractionQueryCondtion qc = new InteractionQueryCondtion();

			if (memberId != null)
				qc.memberIds.add(memberId);

			if (userId != null)
				qc.userIds.add(userId);

			if (interactionType != null)
				qc.interactionTypes.add(interactionType.toString());

			if (dateRange != null) {
				Date date = new Date();
				long ms = date.getTime();
				qc.end = date;

				qc.start = new Date(ms
						- DateUtils.getMilliSecondsFromDateRange(dateRange));
			}

			qc.startIndex = startIndex;
			qc.numResults = numResults;

			InteractionQueryResult result = Interaction
					.query(client, qc, login);

			return new APIResponse().status(Status.SUCCESS).object(result)
					.processingTimeInMS(sw.msElapsed());

		} catch (Exception ex) {
			return Utils.toAPIResponse(ex, showStackTrace, new RequestInfo()
					.client(client).req(req).login(login));
		}
	}

	@ApiMethod(path = "createSubInteraction", httpMethod = HttpMethod.POST)
	public APIResponse createSubInteraction(
			@Nullable @Named("client") String client,
			@Named("interactionId") long interactionId,
			@Named("content") String content,
			@Nullable @Named("showStackTrace") Boolean showStackTrace,
			HttpServletRequest req, User user) {

		if (null == client)
			client = "isha";

		String login = null;

		try {
			StopWatch sw = StopWatch.createStarted();
			login = Utils.getLoginEmail(user);

			Interaction.createSubInteraction(client, interactionId, content,
					new Date(), login);

			return new APIResponse().status(Status.SUCCESS)
					.message("Added sub interaction")
					.processingTimeInMS(sw.msElapsed());

		} catch (Exception ex) {
			return Utils.toAPIResponse(ex, showStackTrace, new RequestInfo()
					.client(client).req(req).login(login));
		}
	}

	@ApiMethod(path = "deleteSubInteraction", httpMethod = HttpMethod.DELETE)
	public APIResponse deleteSubInteraction(
			@Nullable @Named("client") String client,
			@Named("interactionId") long interactionId,
			@Named("subInteractionId") long subInteractionId,
			@Nullable @Named("showStackTrace") Boolean showStackTrace,
			HttpServletRequest req, User user) {

		if (null == client)
			client = "isha";

		String login = null;

		try {
			StopWatch sw = StopWatch.createStarted();

			login = Utils.getLoginEmail(user);

			Interaction.deleteSubInteraction(client, interactionId,
					subInteractionId, login);

			return new APIResponse()
					.status(Status.SUCCESS)
					.message(
							"Sub interaction [" + subInteractionId
									+ "] deleted")
					.processingTimeInMS(sw.msElapsed());

		} catch (Exception ex) {
			return Utils.toAPIResponse(ex, showStackTrace, new RequestInfo()
					.client(client).req(req).login(login));
		}
	}

	@ApiMethod(path = "updateSubInteraction", httpMethod = HttpMethod.POST)
	public APIResponse updateSubInteraction(
			@Nullable @Named("client") String client,
			@Named("interactionId") long interactionId,
			@Named("subInteractionId") long subInteractionId,
			@Named("content") String content,
			@Nullable @Named("showStackTrace") Boolean showStackTrace,
			HttpServletRequest req, User user) {

		if (null == client)
			client = "isha";

		String login = null;

		try {
			StopWatch sw = StopWatch.createStarted();
			login = Utils.getLoginEmail(user);

			Interaction.updateSubInteraction(client, interactionId,
					subInteractionId, content, login);

			return new APIResponse()
					.status(Status.SUCCESS)
					.message(
							"Sub interaction [" + subInteractionId
									+ "] updated")
					.processingTimeInMS(sw.msElapsed());

		} catch (Exception ex) {
			return Utils.toAPIResponse(ex, showStackTrace, new RequestInfo()
					.client(client).req(req).login(login));
		}
	}
}
